home *** CD-ROM | disk | FTP | other *** search
/ Aminet 24 / Aminet 24 (1998)(GTI - Schatztruhe)[!][Apr 1998].iso / Aminet / dev / c / cxref_1_4a.lha / cflow.el < prev    next >
Lisp/Scheme  |  1997-04-10  |  6KB  |  201 lines

  1. ;;; CFLOW.EL --- C flow graph 
  2.  
  3. ;; Copyright (C) 1997 Paul Barham
  4.  
  5. ;; Author: Paul Barham Paul.Barham@cl.cam.ac.uk
  6. ;; Maintainer: Paul Barham Paul.Barham@cl.cam.ac.uk
  7. ;; Created: 19 Mar 1997
  8. ;; Version: 1.0
  9. ;; Keywords: C language cxref flow static call graph browser
  10.  
  11.  
  12. ;; This program is free software; you can redistribute it and/or modify
  13. ;; it under the terms of the GNU General Public License as published by
  14. ;; the Free Software Foundation; either version 1, or (at your option)
  15. ;; any later version.
  16.  
  17. ;; This program is distributed in the hope that it will be useful,
  18. ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
  19. ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  20. ;; GNU General Public License for more details.
  21.  
  22. ;; A copy of the GNU General Public License can be obtained from this
  23. ;; program's author (send electronic mail to Paul.Barham@cl.cam.ac.uk)
  24. ;; or from the Free Software Foundation, Inc., 675 Mass Ave,
  25. ;; Cambridge, MA 02139, USA.
  26.  
  27. ;; LCD Archive Entry:
  28. ;; cflow|Paul Barham|Paul.Barham@cl.cam.ac.uk
  29. ;; |C flow graph 
  30. ;; |$Date$|$Revision$|~/packages/cflow.el
  31.  
  32. ;;; Commentary:
  33.  
  34. ;; This package is intended to be used in conjunction with cxref
  35. ;; packeage (http://www.gedanken.demon.co.uk/cxref/index.html)
  36.  
  37. ;; It parses the cxref.function file generated by cxref and fires up 
  38. ;; a sort of folding mode which allows the hierarchical flow graph
  39. ;; to be recursively expanded.  
  40. ;;
  41. ;; Simply find the file cxref.function in a buffer and type M-x cflow
  42. ;;
  43. ;; Then you can use:
  44. ;;
  45. ;; SPC or RETURN   Expand the current line
  46. ;; x               Close up the flow graph under the current node
  47. ;; .               Find the function on the current line in another window
  48. ;; q               Quit
  49. ;;
  50.  
  51. ;;; Change log:
  52. ;; $Log$
  53.  
  54. ;;; Variables:
  55.  
  56. (defvar cflow-filenames t 
  57.   "Show filenames where each function is declared")
  58.  
  59. (defvar cflow-main "main" 
  60.   "The name of the function at the root of the flowgraph")
  61.  
  62. (defvar cflow-indent "|   " 
  63.   "The indentation string added per-level of the flowgraph")
  64.  
  65. ;;; Code:
  66.  
  67. ;;;
  68. ;;; This reads in the output of cxref 
  69. ;;;
  70. (defun cxref-readline ()
  71.   (interactive)
  72.   (let (file fn scope refs 
  73.     (eol (progn (end-of-line) (point))))
  74.     (beginning-of-line)
  75.     (re-search-forward "\\([^ \t]+\\)[ \t]*" eol t) 
  76.     (setq file (buffer-substring-no-properties 
  77.         (match-beginning 1) (match-end 1)))
  78.     (re-search-forward "\\([^ \t]+\\)[ \t]*" eol t) 
  79.     (setq fn   (buffer-substring-no-properties 
  80.         (match-beginning 1) (match-end 1)))
  81.     (re-search-forward "\\([0-9]+\\)[ \t]*" eol t) 
  82.     (setq scope (car (read-from-string
  83.               (buffer-substring-no-properties 
  84.                (match-beginning 1) (match-end 1)))))
  85.     (setq refs nil)
  86.     (while (re-search-forward "\\([^ \t]+\\)[ \t]*" eol t) 
  87.       (setq refs (cons (buffer-substring-no-properties 
  88.             (match-beginning 1) (match-end 1)) refs)))
  89.     (list fn file scope (nreverse refs))
  90.   ))
  91.  
  92. (defun cxref-parse ()
  93.   (interactive)
  94.   (let (fns)
  95.     (save-excursion 
  96.       (beginning-of-buffer)
  97.       (while (< (point) (point-max))
  98.     (setq fns (cons (cxref-readline) fns))
  99.     (forward-line 1))
  100.       )
  101.     fns)
  102. )
  103.  
  104. (defun cflow-insert (indent fname)
  105.   (string-match "[&%]*\\(.*\\)" fname)
  106.   (let* ((basename (substring fname (match-beginning 1)))
  107.      (fun (assoc basename cflow-fns)))
  108.     (if fun 
  109.     (insert (concat indent 
  110.             fname
  111.             (if cflow-filenames
  112.                 (concat " (" (nth 1 fun) ")")
  113.               "")
  114.             "\n"))
  115.       (insert (concat indent fname "\n")))
  116.     ))
  117.   
  118. (defun cflow-expand ()
  119.   "Expand this node in the flow graph"
  120.   (interactive)
  121.   (let (name indent fun)
  122.     (save-excursion
  123.       (beginning-of-line)
  124.       (re-search-forward "\\(^[| ]*\\)[&%]*\\([*a-zA-Z0-9_$]+\\)")
  125.       (setq indent (concat (buffer-substring-no-properties 
  126.                  (match-beginning 1)
  127.                  (match-end 1)) cflow-indent))
  128.       (setq name (buffer-substring-no-properties 
  129.          (match-beginning 2)
  130.          (match-end 2)))
  131.       (setq fun (assoc name cflow-fns))
  132.       (forward-line 1)
  133.       (beginning-of-line)
  134.       (or (looking-at indent)
  135.       (mapcar (lambda (fname) 
  136.             (cflow-insert indent fname))
  137.           (nth 3 fun)))
  138.  
  139.       ))
  140. )
  141. (defun cflow-contract ()
  142.   "Close up this section of the flow graph"
  143.   (interactive)
  144.   (let (name indent fun)
  145.     (save-excursion
  146.       (beginning-of-line)
  147.       (re-search-forward "\\(^[| ]*\\)")
  148.       (setq indent (concat (buffer-substring-no-properties 
  149.                  (match-beginning 1)
  150.                  (match-end 1)) cflow-indent))
  151.       (forward-line 1)
  152.       (beginning-of-line)
  153.       (while (looking-at indent)
  154.     (kill-line 1))
  155.       ))
  156. )  
  157.  
  158. (defun cflow-tag ()
  159.   "Find the function on the current line using TAGS"
  160.   (interactive)
  161.   (let (name indent fun)
  162.     (save-excursion
  163.       (beginning-of-line)
  164.       (re-search-forward "\\(^[| ]*\\)[&%]*\\([*a-zA-Z0-9_$]+\\)")
  165.       (setq indent (concat (buffer-substring-no-properties 
  166.                  (match-beginning 1)
  167.                  (match-end 1)) cflow-indent))
  168.       (setq name (buffer-substring-no-properties 
  169.          (match-beginning 2)
  170.          (match-end 2)))
  171.       (message "Finding %s" name)
  172.       (find-tag-other-window name)))
  173. )
  174.  
  175. (define-derived-mode cflow-mode fundamental-mode "CFlow"
  176.   (setq cflow-mode t)
  177.   ;; Linemenu simply highlights the current line
  178.   ;  (linemenu-initialize) 
  179. )
  180.  
  181. (define-key cflow-mode-map " " 'cflow-expand)    
  182. (define-key cflow-mode-map "" 'cflow-expand)  
  183. (define-key cflow-mode-map "x" 'cflow-contract)    
  184. (define-key cflow-mode-map "." 'cflow-tag)    
  185. (define-key cflow-mode-map "q" 'bury-buffer)    
  186.  
  187. (defun cflow ()
  188.   (interactive)
  189.   (let ((buf (get-buffer-create "*cflow*")))
  190.     (setq cflow-fns (cxref-parse))
  191.     (switch-to-buffer buf)
  192.     (cflow-mode)
  193.     (erase-buffer)
  194.     ;; Don't understand this :-)
  195.     ; (make-local-variable 'cflow-fns)
  196.     (cflow-insert "" "$")
  197.     (cflow-insert "" cflow-main))
  198. )
  199.  
  200. ;;; CFLOW.EL ends here
  201.